package com.suwish.device.util;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.FileListingService;
import com.android.ddmlib.FileListingService.FileEntry;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.RawImage;
import com.android.ddmlib.ShellCommandUnresponsiveException;
import com.android.ddmlib.SyncService;
import com.android.ddmlib.SyncService.SyncResult;
import com.android.ddmlib.TimeoutException;
import com.suwish.device.SyncProgressMonitorAdapter;
import com.suwish.pc.ui.util.DeviceHelper;
import com.suwish.pc.ui.util.UIHelper;
import com.suwish.pc.util.StringUtils;

/**
 * 
 * 
 * 设备工具类，直接对设备的操作方法，其实局势一种封装。</p>
 * 
 * 此类的方法与UI无关，也可以说无需考虑为UI调用带来便利。对于UI的调用原则
 * 可参见设备帮助类的解释{@link DeviceHelper}
 * </p>
 * 
 * 
 * 新版DDMLIB存在文件锁定的问题，现在直接使用源代码，并修改一些设计上的问题。
 * 目前的DDMS库即ddmlib过于粗糙，对外部调用和回调过于简单，下个版本需要大量改造才可以，
 * 如果知道了ADB的socket通信的数据包协议，将会尽可能少的减少对adb命令的依赖。
 * @author Min
 *
 */
public final class DeviceUtils {

	private DeviceUtils() {}

	/**
	 * 
	 * @param device
	 * @param landscape
	 * @return
	 * @throws TimeoutException
	 * @throws AdbCommandRejectedException
	 * @throws IOException
	 */
	public static BufferedImage parseScreenshot(IDevice device, boolean landscape) 
					throws TimeoutException, AdbCommandRejectedException, IOException{
		return parseScreenshot(device.getScreenshot(), landscape);
	}
	/**
	 * 
	 * @param rawImage
	 * @param landscape
	 * @return
	 */
	public static BufferedImage parseScreenshot(RawImage rawImage, boolean landscape){
		int width2 = landscape ? rawImage.height : rawImage.width;
		int height2 = landscape ? rawImage.width : rawImage.height;
		BufferedImage image = new BufferedImage(width2, height2, BufferedImage.TYPE_INT_RGB);
		if (image.getHeight() != height2 || image.getWidth() != width2) {
			image = new BufferedImage(width2, height2, BufferedImage.TYPE_INT_RGB);
		}
		int index = 0;
		int indexInc = rawImage.bpp >> 3;
		for (int y = 0; y < rawImage.height; y++) {
			for (int x = 0; x < rawImage.width; x++, index += indexInc) {
				int value = rawImage.getARGB(index);
				if (landscape)
					image.setRGB(y, rawImage.width - x - 1, value);
				else
					image.setRGB(x, y, value);
			}
		}
		return image;
	}
	/**
	 * 
	 * 返回设备的描述信息，主要的目的是返回尽量详细的描述信息，便于在界面上区分设备。
	 * 
	 * @param device
	 * @return
	 */
	public static String getDeviceInfo4List(IDevice device){
		return device.isEmulator() ? (device.getSerialNumber() + " " + device.getState().toString()) :
			(device.getProperty(Platform.PROP_OR_PRODUCT_MANUFACTURE) + " " + device.getProperty(Platform.PROP_OR_PRODUCT_MODEL)
					+ " "  + device.getState().toString() + " (" + device.getSerialNumber() + ")");
	}
	/**
	 * 
	 * @param device
	 * @param path
	 * @param fileName
	 * @throws TimeoutException
	 * @throws AdbCommandRejectedException
	 * @throws IOException
	 */
	public static void saveScreenshot(IDevice device, String path, String fileName) 
					throws TimeoutException, AdbCommandRejectedException, IOException{
		BufferedImage image = parseScreenshot(device, false);
		
		ImageIO.write(image, "png", new File(path, fileName));
	}
	/**
	 * 
	 * @param device
	 * @param file
	 * @throws TimeoutException
	 * @throws AdbCommandRejectedException
	 * @throws IOException
	 */
	public static void saveScreenshot(IDevice device, File file) 
					throws TimeoutException, AdbCommandRejectedException, IOException{
		BufferedImage image = parseScreenshot(device, false);
		
		ImageIO.write(image, "png", file);
	}
	/**
	 * 
	 * 将本地文件上传到设备的制定路径</p>
	 * 
	 * 新版本的库参数改动好多啊233
	 * 
	 * @param device
	 * @param localFrom
	 * @param remoteTo
	 * @throws IOException 
	 * @throws AdbCommandRejectedException 
	 * @throws TimeoutException 
	 * @throws SyncException 
	 */
	public static void pushFile(IDevice device, final String[] localFrom, final FileEntry remoteTo) 
				throws TimeoutException, AdbCommandRejectedException, IOException{
		SyncService server = device.getSyncService();
		SyncResult result = server.push(localFrom, remoteTo, SyncService.getNullProgressMonitor());
		UIHelper.showMessageDialog(result.getMessage());
//				new SyncProgressMonitorAdapter(){
//			@Override
//			public void stop() {
//				UIHelper.showMessageDialog("upload  " + localFrom[0] + " to " + remoteTo.getFullPath() + " stop");
//
//			}
//		});
	}
	/**
	 * 
	 * 上传文件到设备目录
	 * 
	 * @param device
	 * @param localFrom
	 * @param remoteTo
	 * @throws TimeoutException
	 * @throws AdbCommandRejectedException
	 * @throws IOException
	 * @throws SyncException
	 */
	public static void pushFile(IDevice device, final String localFrom, final String remoteTo) 
			throws TimeoutException, AdbCommandRejectedException, IOException{
		SyncService server = device.getSyncService();
		server.pushFile(localFrom, remoteTo, new SyncProgressMonitorAdapter(){
			@Override
			public void stop() {
				UIHelper.showMessageDialog("upload  " + localFrom + " to " + remoteTo + " stop");

			}
		});
	}
	/**
	 * 从设备拉取文件到本地
	 * 
	 * @param device
	 * @param remoteFrom
	 * @param localTo
	 */
	public static void pullFile(IDevice device, final FileEntry remoteFrom, final String localTo)
			throws TimeoutException, AdbCommandRejectedException, IOException{
		SyncService server = device.getSyncService();
		SyncResult result = server.pullFile(remoteFrom, localTo, SyncService.getNullProgressMonitor());
		UIHelper.showMessageDialog(result.getMessage());
//				new SyncProgressMonitorAdapter(){
//			@Override
//			public void stop() {
//				UIHelper.showMessageDialog("download " + remoteFrom.getName() + " to " + localTo + " stop");
////				server.
//			}
//		});
	}
	/**
	 * 
	 * @param device
	 * @param remoteFrom
	 * @param localTo
	 * @throws TimeoutException
	 * @throws AdbCommandRejectedException
	 * @throws IOException
	 * @throws SyncException
	 */
	public static void pullFile(IDevice device, FileEntry[] remoteFrom, String localTo)
			throws TimeoutException, AdbCommandRejectedException, IOException{
		SyncService server = device.getSyncService();
		server.pull(remoteFrom, localTo, new SyncProgressMonitorAdapter(){
			@Override
			public void stop() {
//				UIHelper.showMessageDialog(parent, message, title, messageType);

			}
		});
	}
	/**
	 * 
	 * @param device
	 * @param entry
	 * @return
	 * @throws TimeoutException
	 * @throws AdbCommandRejectedException
	 * @throws ShellCommandUnresponsiveException
	 * @throws IOException
	 */
	public static FileEntry[] getChildrenEntry(IDevice device, FileEntry entry)
			throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException{
		FileListingService  server = device.getFileListingService();
		return server.getChildren(entry, false, null);
	}
	/**
	 * 
	 * @param device
	 * @return
	 */
	public static FileEntry getRootEntry(IDevice device){
		return device.getFileListingService().getRoot();
	}
	/**
	 * 看ddmib的源码是push到temp，然后远程安装，远程安装使用远程命令的方式，而远程命令有回调。
	 * 
	 * 
	 * 
	 * @param device
	 * @param filePath
	 * @param reinstall
	 * @throws InstallException
	 * 
	 * @version 1.0 由于此方法无法获得进度，将在下个版本被替换。
	 * @throws IOException 
	 * @throws ShellCommandUnresponsiveException 
	 * @throws AdbCommandRejectedException 
	 * @throws TimeoutException 
	 * 
	 */
	public static void installAPK(IDevice device, String filePath, boolean reinstall) 
				throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException{
		String result = device.installPackage(filePath, reinstall);
		UIHelper.showMessageDialog(StringUtils.isEmpty(result) ? "install Success!" : result);
	}
	/**
	 * 
	 * 
	 * @param device
	 * @param packageName
	 * @throws InstallException
	 * 
	 * @version 1.0 由于此方法无法获得进度，将在下个版本被替换。
	 * @throws IOException 
	 * @throws ShellCommandUnresponsiveException 
	 * @throws AdbCommandRejectedException 
	 * @throws TimeoutException 
	 */
	public static void uninstallAPK(IDevice device, String packageName) 
				throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException{
		String result = device.uninstallPackage(packageName);
		UIHelper.showMessageDialog(StringUtils.isEmpty(result) ? "uninstall Success!" : result);
	}
}
